//
//  BMSEncryptionUtil.m
//  BMSSDK
//
//  Created by YeJary on 2025/5/12.
//

#import "BMSEncryptionUtil.h"
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>

@interface BMSEncryptionUtil()

@end

@implementation BMSEncryptionUtil

+ (NSString *)aesEncryptToBase64:(NSString *)json key:(NSString *)key iv:(NSString *)iv {
    NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    NSData *ivData  = [iv dataUsingEncoding:NSUTF8StringEncoding];

    size_t bufferSize = data.length + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,
                                          keyData.bytes,
                                          kCCKeySizeAES128,
                                          ivData.bytes,
                                          data.bytes,
                                          data.length,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSData *encryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        return [encryptedData base64EncodedStringWithOptions:0];
    }
    
    free(buffer);
    return nil;
}

+ (NSString *)generateSignWithParams:(NSDictionary<NSString *, NSString *> *)params secret:(NSString *)secret isRealAuth:(BOOL)auth{
    // 1. 按 key 进行字典序排序
    NSArray *sortedKeys = [[params allKeys] sortedArrayUsingSelector:@selector(compare:)];

    // 2. 组装 key=value（对 value 进行 urlEncode）
    NSMutableArray *components = [NSMutableArray array];
    for (NSString *key in sortedKeys) {
        NSString *value = params[key];
        
        NSString *encodedValue = auth ? value : [self urlEncode:value];
        [components addObject:[NSString stringWithFormat:@"%@=%@", key, encodedValue]];
    }

    // 3. 拼接成 query 字符串
    NSString *queryString = [components componentsJoinedByString:@"&"];

    // 4. 拼接 secret
    NSString *finalString = [queryString stringByAppendingString:secret];

    NSLog(@"md5 之前\n%@",finalString);
    // 5. 生成 MD5
    return [self md5:finalString];
}

+ (NSString *)urlEncode:(NSString *)value {
    NSCharacterSet *allowedSet = [[NSCharacterSet characterSetWithCharactersInString:@"-_.*"] invertedSet];
    NSString *valueStr = [[value description] stringByAddingPercentEncodingWithAllowedCharacters:allowedSet];
    return valueStr;
}

+ (NSString *)md5:(NSString *)string {
    const char *cStr = [string UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [output appendFormat:@"%02x", digest[i]];
    }
    return output;
}

@end
